import os
import time
import sys

from openpyxl.reader.excel import load_workbook

from handler import *


class Logger:
    def __init__(self, filename):
        self.terminal = sys.stdout  # 保留原始控制台输出
        self.log = open(filename, 'a')  # 追加写入文件

    def write(self, message):
        self.terminal.write(message)  # 控制台输出
        self.log.write(message)  # 文件写入

    def flush(self):  # 必须定义（兼容性）
        pass


# 检查程序所在目录下是否有输入文件夹和输出文件夹
def get_files():
    files = []
    try:
        # 若没有输入文件,则创建后程序结束,若有再检查文件夹内是否有文件
        if os.path.isdir('输入文件'):
            if os.listdir('输入文件'):
                files = [f for f in os.listdir('输入文件') if os.path.isfile(os.path.join('输入文件', f))]
                # print(files)
            else:  #
                print('"输入文件"文件夹内不存在数据文件,请放入数据文件并重新启动程序......')
        else:
            os.makedirs('输入文件', exist_ok=True)
            print('"输入文件"文件夹不存在,已经自动创建,请放入数据文件并重新启动程序......')
        # 输出文件夹不存在则创建,暂不需要提示
        os.makedirs('输出文件', exist_ok=True)  # 若存在则不报错
    except Exception as e:
        print(f"文件夹检查发生错误：{e}")
    finally:
        return files


# 对文件夹内的文件一一处理
def runner(files):
    if files:
        # 获取质控规则
        get_rules()
        finish_list = []
        error_list = []
        for file in files:
            input_excel_file = os.path.join('输入文件', file)
            output_file_name = file.split('.')[0] + '_已质控' + '.xlsx'  # 质控后文件名
            output_excel_file = os.path.join('输出文件', output_file_name)
            start_time = time.time()
            # 质控程序,处理成功则为True,否则为False
            finish_ = qc(input_excel_file, output_excel_file)
            end_time = time.time()
            time_cost = round((end_time - start_time) / 60, 2)  # 时间保留两位小数
            if finish_:
                finish_info = f'{file} 质控处理完毕(^▽^),总耗时{time_cost}分钟,结果已保存至"输出文件"文件夹下......'
                print(finish_info)
                finish_list.append(finish_info)
            else:
                error_info = f'{file} 质控处理失败(>﹏<),请检查相关文件'
                error_list.append(error_info)
        f_num = len(finish_list)
        r_num = len(error_list)
        if f_num != 0:
            print('----------------------------------质控处理成功结果如下----------------------------------')
            for f_info in finish_list:
                print(f_info)
        if r_num != 0:
            print('----------------------------------质控处理失败结果如下----------------------------------')
            for r_info in error_list:
                print(r_info)


# 质控主程序
def qc(input_excel_file, output_excel_file):
    finish_flag = False
    try:

        error_list = []
        # 获取质控规则
        # get_rules()
        # 读取预处理文件并进行程序初始化
        df = pd.read_excel(input_excel_file, engine='openpyxl')
        df.to_excel(output_excel_file, index=False, engine='openpyxl')

        # 数据初始化
        initial_data(df)

        # 加载工作簿
        wb = load_workbook(output_excel_file)
        ws = wb.active

        # 执行各个处理函数，进行数据表格的处理
        qc_sum = 15
        # 随访分类
        qc_num = 1
        col_name1 = '随访类型'
        col_name2 = '此次随访分类'
        col_name3 = '血压随访分类'
        col_name4 = '收缩压'
        col_name5 = '舒张压'
        col_name6 = '出生日期'
        col_name7 = '血糖随访分类'
        col_name8 = '空腹血糖'
        try:
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理中......')
            sffl(df, ws, col_name1, col_name2, col_name3, col_name4, col_name5, col_name6, col_name7, col_name8,
                 error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}"
            error_list.append(error_str)
        # 体质指数(BMI)
        qc_num += 1
        col_name1 = '体质指数(BMI)'
        col_name2 = '体重'
        col_name3 = '目标体重'
        try:
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理中......')
            tzzs(df, ws, col_name1, col_name2, col_name3, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}"
            error_list.append(error_str)
        # 随访人
        qc_num += 1
        col_name = '随访人'
        try:
            print(f'({qc_num}/{qc_sum}){col_name}质控处理中......')
            sfr(df, ws, col_name, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name}质控发生错误：{e}"
            error_list.append(error_str)
        # 是否加入国家标准版
        qc_num += 1
        col_name = '是否加入国家标准版'
        try:
            print(f'({qc_num}/{qc_sum}){col_name}质控处理中......')
            sfjrgjbzb(df, ws, col_name, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name}质控发生错误：{e}"
            error_list.append(error_str)
        # 收缩压
        qc_num += 1
        col_name1 = '收缩压'
        col_name2 = '身份证号'
        col_name3 = '随访日期'
        try:
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理中......')
            ssy(df, ws, col_name1, col_name2, col_name3, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}"
            error_list.append(error_str)
        # 舒张压
        qc_num += 1
        col_name1 = '舒张压'
        col_name2 = '身份证号'
        col_name3 = '随访日期'
        try:
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理中......')
            szy(df, ws, col_name1, col_name2, col_name3, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}"
            error_list.append(error_str)
        # 体重
        qc_num += 1
        col_name1 = '体重'
        col_name2 = '身份证号'
        col_name3 = '随访日期'
        try:
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理中......')
            tz(df, ws, col_name1, col_name2, col_name3, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}"
            error_list.append(error_str)
        # 身高
        qc_num += 1
        col_name = '身高'
        try:
            print(f'({qc_num}/{qc_sum}){col_name}质控处理中......')
            sg(df, ws, col_name, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name}质控发生错误：{e}"
            error_list.append(error_str)
        # 心率
        qc_num += 1
        col_name1 = '心率'
        col_name2 = '身份证号'
        col_name3 = '随访日期'
        try:
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理中......')
            xl(df, ws, col_name1, col_name2, col_name3, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}"
            error_list.append(error_str)
        # 主食量
        qc_num += 1
        col_name1 = '主食量'
        col_name2 = '目标主食量'
        try:
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理中......')
            zsl(df, ws, col_name1, col_name2, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}"
            error_list.append(error_str)
        # 随访建议
        qc_num += 1
        col_name0 = '随访建议'
        col_name1 = '身份证号'
        col_name2 = '随访日期'
        col_name3 = '评估'
        col_name4 = '生活方式'
        col_name5 = '医生建议'
        try:
            print(f'({qc_num}/{qc_sum}){col_name0}质控处理中......')
            sfjy(df, ws, col_name1, col_name2, col_name3, col_name4, col_name5, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name0}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name0}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name0}质控发生错误：{e}"
            error_list.append(error_str)
        # 吸烟
        qc_num += 1
        col_name1 = '日吸烟量'
        col_name2 = '目标日吸烟量'
        try:
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理中......')
            xy(df, ws, col_name1, col_name2, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}"
            error_list.append(error_str)
        # 饮酒
        qc_num += 1
        col_name1 = '日饮酒量'
        col_name2 = '目标日饮酒量'
        try:
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理中......')
            yj(df, ws, col_name1, col_name2, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}"
            error_list.append(error_str)
        # 运动次数
        qc_num += 1
        col_name1 = '运动次数'
        col_name2 = '目标运动次数'
        try:
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理中......')
            ydcs(df, ws, col_name1, col_name2, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}"
            error_list.append(error_str)
        # 运动时间
        qc_num += 1
        col_name1 = '运动时间'
        col_name2 = '目标运动时间'
        try:
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理中......')
            ydsj(df, ws, col_name1, col_name2, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name1}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name1}质控发生错误：{e}"
            error_list.append(error_str)
        # 症状编辑框
        qc_num += 1
        col_name1 = '身份证号'
        col_name2 = '随访日期'
        col_name3 = '症状编辑框'
        try:
            print(f'({qc_num}/{qc_sum}){col_name3}质控处理中......')
            zzbjk(df, ws, col_name1, col_name2, col_name3, error_list)
            # wb.save(output_excel_file) # 等各项处理完后一次性保存
            print(f'({qc_num}/{qc_sum}){col_name3}质控处理完毕......')
        except Exception as e:
            print(f"({qc_num}/{qc_sum}){col_name3}质控发生错误：{e}")
            error_str = f"({qc_num}/{qc_sum}){col_name3}质控发生错误：{e}"
            error_list.append(error_str)
        # 收尾工作，查看是否有报错信息
        try:
            if len(error_list) == 0:
                wb.save(output_excel_file)
                wb.close()
                finish_flag = True
                # print(f'质控处理完毕 (*^▽^*)......')
            else:
                if os.path.exists(output_excel_file):
                    os.remove(output_excel_file)
                print('质控处理中出现下列问题：')
                for err in error_list:
                    print(err)
        except Exception as e:
            print(f"收尾程序有误：{e}")

    except Exception as e:
        print(f"程序初始化发生错误：{e}")
        if os.path.exists(output_excel_file):
            os.remove(output_excel_file)
    finally:
        return finish_flag


if __name__ == '__main__':
    log_switch = True  # 设置为True时将保存运行时控制台输出内容
    if log_switch:
        with open('执行日志.log', 'w') as log_file:
            log_file.write('')  # 为节省空间，只保存最近一次的执行日志
        sys.stdout = Logger('执行日志.log')
        print('日志内容开始写入,当前时间:' + datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
    print('在执行本程序前,请确保预处理数据文件放在与程序相同路径下的名为"输入文件"的文件夹下')
    time.sleep(1)
    runner(get_files())
    # time.sleep(2)
    # input('按Enter键退出')
